package com.owc.service.impl.admin;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.owc.common.Const.Const;
import com.owc.common.tool.*;
import com.owc.dao.AdminUserMapper;
import com.owc.dao.SystemConfigMapper;
import com.owc.dao.UpdateRecordMapper;
import com.owc.domain.DO.UpdateRecordDO;
import com.owc.domain.PageBean;
import com.owc.domain.dto.admin.SystemConfigDTO;
import com.owc.domain.dto.admin.UpdateRecordDTO;
import com.owc.domain.entity.AdminUser;
import com.owc.domain.entity.SystemConfig;
import com.owc.domain.entity.UpdateRecord;
import com.owc.domain.vo.admin.ModifyVoAdmin;
import com.owc.domain.vo.admin.RateConfigVo;
import com.owc.domain.vo.admin.SystemConfigVo;
import com.owc.filter.content.SecurityContextHolder;
import com.owc.service.admin.SystemService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

/**
 * @Author Jackies
 * @Date 2019/12/18 23:23
 * @Description TODO://
 **/
@Service
public class SystemServiceImpl implements SystemService {

	@Resource
	private SystemConfigMapper systemConfigMapper;
	@Resource
	private AdminUserMapper adminUserMapper;
	@Resource
	private UpdateRecordMapper updateRecordMapper;

	/**
	 * 这儿设计数据结构的时候脑壳被门夹了.... 好吧.赶时间的缘故,垃圾代码奉上
	 */
	@Override
	public SystemConfigDTO getSystemConfig() {

		SystemConfigDTO systemConfigDTO = new SystemConfigDTO();

		SystemConfigDTO.ChianBean chianBean = new SystemConfigDTO.ChianBean();
		SystemConfigDTO.ExchangeBean exchangeBean = new SystemConfigDTO.ExchangeBean();

		List<SystemConfig> systemConfigList = systemConfigMapper.selectAll();

		systemConfigList.forEach(systemConfig -> {
			String key = systemConfig.getKey();
			String value = systemConfig.getValue();
			switch (key){
				case Const.EBC:
					chianBean.setEBC(value);
					break;
				case Const.OWC:
					chianBean.setOWC(value);
					break;
				case Const.BTC:
					chianBean.setBTC(value);
					break;
				case Const.ETH:
					chianBean.setETH(value);
					break;
				case Const.USDT_omni:
					chianBean.setUSDT_omni(value);
					break;
				case Const.USDT_ERC20:
					chianBean.setUSDT_ERC20(value);
					break;
				case Const.BTC_blockNum:
					chianBean.setBTC_blockNum(value);
					break;
				case Const.ETH_blockNum:
					chianBean.setETH_blockNum(value);
					break;
				case Const.h5Url:
					systemConfigDTO.setH5Url(value);
					break;
				case Const.EBC_OWC_RATE:
					exchangeBean.setEBC_OWC_RATE(value);
					break;
				case Const.ETH_EBC_RATE:
					exchangeBean.setETH_EBC_RATE(value);
					break;
				case Const.USDT_ERC20_EBC_RATE:
					exchangeBean.setUSDT_ERC20_EBC_RATE(value);
				default:
					break;
			}
		});
		systemConfigDTO.setChian(chianBean);
		systemConfigDTO.setExchangeBean(exchangeBean);
		return systemConfigDTO;
	}

	@Override
	public Boolean updateConfig(SystemConfigVo systemConfigVo) {

		HashMap<String,String> configMap = new HashMap<>();

		configMap.put(Const.EBC,systemConfigVo.getEBC());
		configMap.put(Const.OWC,systemConfigVo.getOWC());
		configMap.put(Const.BTC,systemConfigVo.getBTC());
		configMap.put(Const.ETH,systemConfigVo.getETH());
		configMap.put(Const.USDT_omni,systemConfigVo.getUSDT_omni());
		configMap.put(Const.USDT_ERC20,systemConfigVo.getUsdt_ERC20());
		configMap.put(Const.BTC_blockNum,systemConfigVo.getBTC_blockNum());
		configMap.put(Const.ETH_blockNum,systemConfigVo.getETH_blockNum());
		if(systemConfigVo.getH5Url() != null){
			configMap.put(Const.h5Url,systemConfigVo.getH5Url().isEmpty() ? " " : systemConfigVo.getH5Url());
		}
		configMap.keySet().forEach(key -> {
			String value = configMap.get(key);
			if(value == null || "".equals(value)){
				return;
			}
			systemConfigMapper.updateValueByKey(key,value);
		});
		return true;
	}

	@Override
	public Boolean modifyPassword(ModifyVoAdmin modifyVoAdmin) {

		Assert.isTrue((modifyVoAdmin.getPassword().equals(modifyVoAdmin.getConfirmPassword())),"2次输入密码不一致");

		AdminUser adminUser = adminUserMapper.selectByPrimaryKey(SecurityContextHolder.getCurrentUserId());
		Assert.notNull(adminUser,"异常的用户");
		Assert.isTrue((adminUser.getPassword().equals(modifyVoAdmin.getCurrentPassword())),"原始密码输入错误");

		adminUserMapper.updatePassword(SecurityContextHolder.getCurrentUserId(),modifyVoAdmin.getPassword());
		return true;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public Boolean updateRateConfig(RateConfigVo rateConfigVo) {

		List<UpdateRecord> updateRecords = new ArrayList<>();

		if(rateConfigVo.getEBC_OWC_RATE() != null){
			updateRecords.add(loadRecord("EBC转OWC汇率",systemConfigMapper.selectByKey(Const.EBC_OWC_RATE),rateConfigVo.getEBC_OWC_RATE().toPlainString()));
			systemConfigMapper.updateValueByKey(Const.EBC_OWC_RATE,rateConfigVo.getEBC_OWC_RATE().toPlainString());
		}

		if(rateConfigVo.getUSDT_ERC20_EBC_RATE() != null){
			updateRecords.add(loadRecord("USDT(EC20)转EBC汇率",systemConfigMapper.selectByKey(Const.USDT_ERC20_EBC_RATE),rateConfigVo.getUSDT_ERC20_EBC_RATE().toPlainString()));
			systemConfigMapper.updateValueByKey(Const.USDT_ERC20_EBC_RATE,rateConfigVo.getUSDT_ERC20_EBC_RATE().toPlainString());
		}

		if(rateConfigVo.getETH_EBC_RATE() != null){
			updateRecords.add(loadRecord("Eth转EBC汇率",systemConfigMapper.selectByKey(Const.ETH_EBC_RATE),rateConfigVo.getETH_EBC_RATE().toPlainString()));
			systemConfigMapper.updateValueByKey(Const.ETH_EBC_RATE,rateConfigVo.getETH_EBC_RATE().toPlainString());
		}
		updateRecordMapper.batchInsert(updateRecords);
		return true;
	}

	@Override
	public PageBean<UpdateRecordDTO> getUpdateRateConfigLogs(Integer pageIndex, Integer pageSize) {
		PageHelper.startPage(pageIndex,pageSize);
		List<UpdateRecord> list = updateRecordMapper.selectByTime();
		PageInfo<UpdateRecord> pageInfo = new PageInfo<>(list);
		return PageBean.pageBean(pageInfo.getTotal(),BeanUtils.coventObject(pageInfo.getList(),UpdateRecordDTO.class));
	}

	@Override
	public <T> T getConfigValue(String key,Class<T> cls) {
		Assert.notNull(key,"Get system config. Key must not be null.");
		if(cls == null){
			cls = (Class<T>) String.class;
		}
		String value = systemConfigMapper.selectByKey(key);
		if(value == null){
			return null;
		}
		return JSON.parseObject(value,cls);
	}

	private UpdateRecord loadRecord(String functionName, String oldVal, String newVal){
		UpdateRecordDO record = new UpdateRecordDO();
		record.setFunctionName(functionName);
		record.setNewValue(newVal);
		record.setOldValue(oldVal);
		record.setTime(DateUtils.formatYMDHMS(new Date()));
		record.setUpdateUserId(SecurityContextHolder.getCurrentUserId());
		record.setUpdateUserName(SecurityContextHolder.getCurrentUserName());
		record.loadDesc();
		return BeanUtils.transformFrom(record,UpdateRecord.class);
	}
}
